package com.neusoft.hifly.attachment.file.service.impl;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import com.neusoft.hifly.attachment.file.dao.IFileLogDao;
import com.neusoft.hifly.attachment.file.entity.FileLogObj;
import com.neusoft.hifly.attachment.file.service.IFileLogService;
import com.neusoft.hifly.commons.exception.SystemErrorException;
import com.neusoft.hifly.commons.lang.StringConstants;
import com.neusoft.hifly.core.basic.service.impl.CTSaaSBaseServiceImpl;
import com.neusoft.hifly.core.log.annotation.LogType;
import com.neusoft.hifly.core.log.annotation.OperationLog;
import com.neusoft.hifly.dynamicds.multi.annotation.MultiDynamicRoutingDataSource;

/**
 * Title: 附件服务
 * <p>
 * Description: 附件_附件表历史记录 Service
 * <p>
 * Copyright: 2019
 * <p>
 * Company: 东软汉枫
 *
 * @author lh_neu
 * @version 1.0.0
 */
@Service
@MultiDynamicRoutingDataSource
public class FileLogServiceImpl extends CTSaaSBaseServiceImpl implements IFileLogService {
	@Autowired(required = false)
	private IFileLogDao fileLogDao;

	/**
	 * 保存对象
	 *
	 * @param organCode
	 *            租户编码
	 * @param organLogicId
	 *            租户逻辑ID
	 * @param obj
	 *            对象
	 * @throws SystemErrorException
	 *             自定义异常
	 */
	@Override
	@OperationLog(method = LogType.UPDATE, msg = "附件表历史")
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = { Exception.class, RuntimeException.class })
	public void saveOrUpdate(final String organCode, final long organLogicId, final FileLogObj obj)
			throws SystemErrorException {
		if (StringUtils.isEmpty(organCode) || obj == null) {
			return;
		}

		final FileLogObj oldObj = fileLogDao.getById(organCode, obj.getId());

		obj.setOrganLogicId(organLogicId);

		// 有ID的话要判断是否保存还是更新
		if (oldObj == null) {
			// 保存
			obj.setLogTime(LocalDateTime.now());

			this.setForm(obj, obj);

			fileLogDao.insert(obj);
		} else {
			// 更新

			this.setForm(obj, oldObj);

			oldObj.setLogTime(LocalDateTime.now());

			fileLogDao.updateById(oldObj);
		}
	}

	/**
	 * 根据ID删除对象
	 *
	 * @param organCode
	 *            租户编码
	 * @param id
	 *            对象ID
	 */
	@Override
	@OperationLog(method = LogType.DELETE, msg = "附件表历史")
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = { Exception.class, RuntimeException.class })
	public void deleteById(final String organCode, final int id) {
		if (StringUtils.isEmpty(organCode)) {
			return;
		}

		fileLogDao.deleteById(organCode, id);
	}

	/**
	 * 批量删除对象
	 *
	 * @param organCode
	 *            租户编码
	 * @param ids
	 *            对象ID，多id使用英文逗号分隔
	 */
	@Override
	public void deleteByBatch(final String organCode, final String ids) {
		if (StringUtils.isEmpty(organCode) || StringUtils.isEmpty(ids)) {
			return;
		}
		final String[] idArr = ids.split(StringConstants.STRING_SPLIT_FLAG_3);
		if (idArr == null) {
			return;
		}
		for (final String id : idArr) {
			if (StringUtils.isEmpty(id) || !StringUtils.isNumeric(id)) {
				continue;
			}
			this.deleteById(organCode, Integer.parseInt(id));
		}
	}

	/**
	 * 删除多余的
	 *
	 * @param organCode
	 *            租户编码
	 * @param organLogicId
	 *            租户逻辑ID
	 * @param count
	 *            历史记录总数
	 * @param fileLogicId
	 *            附件ID
	 */
	@Override
	public void deleteMore(final String organCode, final long organLogicId, final int count, final long fileLogicId) {
		if (StringUtils.isEmpty(organCode)) {
			return;
		}

		final List<FileLogObj> ret = fileLogDao.findByFileLogicId(organCode, organLogicId, fileLogicId);
		final StringBuffer sb = new StringBuffer("");
		for (final FileLogObj attachmentLog : ret) {
			sb.append("" + attachmentLog.getId() + "" + StringConstants.STRING_SPLIT_FLAG_3);
		}
		if (sb.length() >= 1) {
			sb.delete(sb.length() - 1, sb.length());
		}
		if (StringUtils.isEmpty(sb.toString())) {
			return;
		}
		fileLogDao.deleteMore(organCode, fileLogicId, sb.toString());
	}

	/**
	 * 根据id查询对象
	 *
	 * @param organCode
	 *            租户编码
	 * @param id
	 *            对象ID
	 * @return 对象
	 */
	@Override
	public FileLogObj getById(final String organCode, final int id) {
		if (StringUtils.isEmpty(organCode)) {
			return null;
		}
		return fileLogDao.getById(organCode, id);
	}

	/**
	 * 查询所有对象
	 *
	 * @param organCode
	 *            租户编码
	 * @param organLogicId
	 *            租户逻辑ID
	 * @return 对象集合
	 */
	@Override
	public List<FileLogObj> findAll(final String organCode, final long organLogicId) {
		if (StringUtils.isEmpty(organCode)) {
			return null;
		}
		return fileLogDao.findAll(organCode, organLogicId);
	}

	/**
	 * 主附件查询所有对象
	 *
	 * @param organCode
	 *            租户编码
	 * @param organLogicId
	 *            租户逻辑ID
	 * @param fileLogicId
	 *            主附件逻辑ID
	 * @return 对象集合
	 */
	@Override
	public List<FileLogObj> findByFileLogicId(final String organCode, final long organLogicId, final long fileLogicId) {
		if (StringUtils.isEmpty(organCode)) {
			return null;
		}
		return fileLogDao.findByFileLogicId(organCode, organLogicId, fileLogicId);
	}

	/**
	 * 根据条件查询
	 *
	 * @param organCode
	 *            租户编码
	 * @param organLogicId
	 *            租户逻辑ID
	 * @param property
	 *            参数。其中isLike:Boolean 是否模糊查询
	 * @return 集合
	 */
	@Override
	public List<FileLogObj> search(final String organCode, final long organLogicId, Map<String, Object> property) {
		if (StringUtils.isEmpty(organCode)) {
			return null;
		}
		if (property == null) {
			property = new HashMap<String, Object>(1);
			property.put("organLogicId", organLogicId);
		}
		final QueryWrapper<FileLogObj> queryWrapper = new QueryWrapper<FileLogObj>();
		replaceProperty(property);
		createSql(property, queryWrapper, new String[] { "FILE_ORDER", "LOG_TIME" });
		return fileLogDao.selectList(queryWrapper);
	}

	/**
	 * 根据条件查询
	 *
	 * @param organCode
	 *            租户编码
	 * @param organLogicId
	 *            租户逻辑ID
	 * @param offset
	 *            当前页数
	 * @param limit
	 *            分页长度
	 * @param property
	 *            参数。其中isLike:Boolean 是否模糊查询
	 * @return 返回Map
	 */
	@Override
	public IPage<FileLogObj> search(final String organCode, final long organLogicId, final int offset, final int limit,
			Map<String, Object> property) {
		if (StringUtils.isEmpty(organCode)) {
			return null;
		}
		if (property == null) {
			property = new HashMap<String, Object>(1);
			property.put("organLogicId", organLogicId);
		}
		final IPage<FileLogObj> page = new Page<FileLogObj>(offset, limit);
		final QueryWrapper<FileLogObj> queryWrapper = new QueryWrapper<FileLogObj>();
		replaceProperty(property);
		createSql(property, queryWrapper, new String[] { "FILE_ORDER", "LOG_TIME" });
		return fileLogDao.selectPage(page, queryWrapper);
	}

	/**
	 * 复制信息
	 *
	 * @param fromObj
	 *            原信息
	 * @param toObj
	 *            新信息
	 */
	private void setForm(final FileLogObj fromObj, final FileLogObj toObj) {
		toObj.setOrganLogicId(fromObj.getOrganLogicId());
		toObj.setFileLogicId(fromObj.getFileLogicId());
		toObj.setObjLogicId(fromObj.getObjLogicId());
		toObj.setLogTime(fromObj.getLogTime());
		toObj.setOldFileName(StringUtils.trimToEmpty(fromObj.getOldFileName()));
		toObj.setNewFileName(StringUtils.trimToEmpty(fromObj.getNewFileName()));
		toObj.setFileLength(fromObj.getFileLength());
		toObj.setFileType(StringUtils.trimToEmpty(fromObj.getFileType()));
		toObj.setPath(StringUtils.trimToEmpty(fromObj.getPath()));
		toObj.setFileOrder(fromObj.getFileOrder());
		toObj.setTempId(fromObj.getTempId());
		toObj.setDocType(StringUtils.trimToEmpty(fromObj.getDocType()));
		toObj.setFileUrl(StringUtils.trimToEmpty(fromObj.getFileUrl()));
		toObj.setUserId(fromObj.getUserId());
		toObj.setExt1(StringUtils.trimToEmpty(fromObj.getExt1()));
		toObj.setExt2(StringUtils.trimToEmpty(fromObj.getExt2()));
		toObj.setExt3(StringUtils.trimToEmpty(fromObj.getExt3()));
		toObj.setExt4(StringUtils.trimToEmpty(fromObj.getExt4()));
		toObj.setExt5(StringUtils.trimToEmpty(fromObj.getExt5()));

	}

	/**
	 * 将对象属性替换成数据库列
	 *
	 * @param property
	 *            参数
	 */
	private void replaceProperty(final Map<String, Object> property) {
		if (property != null) {
			if (property.containsKey("organLogicId")) {
				property.put("ORGAN_LOGIC_ID", property.get("organLogicId"));
				property.remove("organLogicId");
			}
			if (property.containsKey("fileLogicId")) {
				property.put("FILE_LOGIC_ID", property.get("fileLogicId"));
				property.remove("fileLogicId");
			}
			if (property.containsKey("objLogicId")) {
				property.put("OBJ_LOGIC_ID", property.get("objLogicId"));
				property.remove("objLogicId");
			}
			if (property.containsKey("logTime")) {
				property.put("LOG_TIME", property.get("logTime"));
				property.remove("logTime");
			}
			if (property.containsKey("oldFileName")) {
				property.put("OLD_FILE_NAME", property.get("oldFileName"));
				property.remove("oldFileName");
			}
			if (property.containsKey("newFileName")) {
				property.put("NEW_FILE_NAME", property.get("newFileName"));
				property.remove("newFileName");
			}
			if (property.containsKey("fileLength")) {
				property.put("FILE_LENGTH", property.get("fileLength"));
				property.remove("fileLength");
			}
			if (property.containsKey("fileType")) {
				property.put("FILE_TYPE", property.get("fileType"));
				property.remove("fileType");
			}
			if (property.containsKey("path")) {
				property.put("PATH", property.get("path"));
				property.remove("path");
			}
			if (property.containsKey("fileOrder")) {
				property.put("FILE_ORDER", property.get("fileOrder"));
				property.remove("fileOrder");
			}
			if (property.containsKey("tempId")) {
				property.put("TEMP_ID", property.get("tempId"));
				property.remove("tempId");
			}
			if (property.containsKey("docType")) {
				property.put("DOC_TYPE", property.get("docType"));
				property.remove("docType");
			}
			if (property.containsKey("fileUrl")) {
				property.put("FILE_URL", property.get("fileUrl"));
				property.remove("fileUrl");
			}
			if (property.containsKey("userId")) {
				property.put("USER_ID", property.get("userId"));
				property.remove("userId");
			}
			if (property.containsKey("createTime")) {
				property.put("CREATE_TIME", property.get("createTime"));
				property.remove("createTime");
			}
			if (property.containsKey("ext1")) {
				property.put("EXT1", property.get("ext1"));
				property.remove("ext1");
			}
			if (property.containsKey("ext2")) {
				property.put("EXT2", property.get("ext2"));
				property.remove("ext2");
			}
			if (property.containsKey("ext3")) {
				property.put("EXT3", property.get("ext3"));
				property.remove("ext3");
			}
			if (property.containsKey("ext4")) {
				property.put("EXT4", property.get("ext4"));
				property.remove("ext4");
			}
			if (property.containsKey("ext5")) {
				property.put("EXT5", property.get("ext5"));
				property.remove("ext5");
			}

		}
	}
}